package tq.com.download;

import android.os.AsyncTask;

import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.concurrent.TimeUnit;

import okhttp3.Call;
import okhttp3.Interceptor;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.ResponseBody;
import okio.Buffer;
import okio.BufferedSource;
import okio.ForwardingSource;
import okio.Okio;
import okio.Source;

public class TQDownloadTask extends AsyncTask<String, Long, Integer> {
    static private int RESULT_SUCESS = 0;
    static private int RESULT_FAIL = 1;
    static private String TAG = "TQDownloadTask";

    private TQDownloadManager.Build mBuild;

    private OkHttpClient mHttpClient;
    private Call mCall;

    public TQDownloadTask(TQDownloadManager.Build pBuild){
        mBuild = pBuild;
    }

    @Override
    protected Integer doInBackground(String... pStrings) {
        if(pStrings.length <= 0)return RESULT_FAIL;

        mHttpClient = new OkHttpClient.Builder()
                .connectTimeout(30, TimeUnit.SECONDS)
                .addNetworkInterceptor(new Interceptor() {
                    @Override
                    public Response intercept(Chain chain) throws IOException {
                        Response lBody = chain.proceed(chain.request());
                        return lBody.newBuilder()
                                .body(new ResponseProgressBody(lBody.body()))
                                .build();
                    }
                })
                .build();

        Request.Builder lBuilder = new Request.Builder()
                .url(mBuild.getUrl())
                .get();

        mkHeader(lBuilder, mBuild.getHeader());

        InputStream is = null;
        try {
            mCall = mHttpClient.newCall(lBuilder.build());
            Response lResponse = mCall.execute();

            try {

                if(lResponse.code() == 200){
                    is = lResponse.body().byteStream();
                    mBuild.save(is);
                }else{
                    return RESULT_FAIL;
                }

            }catch (Exception pE){
                pE.printStackTrace();
            }finally {
                if(is != null){
                    try {
                        is.close();
                    }catch (Exception pE){

                    }
                }
            }

        }catch (Exception pE){
            pE.printStackTrace();
        }
        return RESULT_SUCESS;
    }

    @Override
    protected void onProgressUpdate(Long... values) {
        super.onProgressUpdate(values);

        if(mBuild != null && values.length >= 2){
            mBuild.process(values[0], values[1]);
        }
    }

    @Override
    protected void onCancelled(Integer pInteger) {
        super.onCancelled(pInteger);
        mCall.cancel();
    }

    @Override
    protected void onPostExecute(Integer pInteger) {
        super.onPostExecute(pInteger);

        if(pInteger == RESULT_SUCESS && mBuild !=null) {
            mBuild.success(null);
        }else{
            mBuild.fail("文件下载失败");
        }
    }

    private void mkHeader(Request.Builder pBuilder, HashMap<String, String> header){
        if(header == null || header.size() == 0) return;

        for (HashMap.Entry<String, String> entry:
                header.entrySet()) {
            pBuilder.addHeader(entry.getKey(), entry.getValue());
        }
    }

    public class ResponseProgressBody extends ResponseBody {

        private final ResponseBody mResponseBody;
        private BufferedSource bufferedSource;

        public ResponseProgressBody(ResponseBody responseBody) {
            this.mResponseBody = responseBody;
        }

        @Override
        public MediaType contentType() {
            return mResponseBody.contentType();
        }

        @Override
        public long contentLength() {
            return mResponseBody.contentLength();
        }

        @Override
        public BufferedSource source() {
            if (bufferedSource == null) {
                bufferedSource = Okio.buffer(source(mResponseBody.source()));
            }
            return bufferedSource;
        }

        private Source source(Source source) {

            return new ForwardingSource(source) {

                long totalBytesRead;

                @Override
                public long read(Buffer sink, long byteCount) throws IOException {
                    long bytesRead = super.read(sink, byteCount);
                    totalBytesRead += ((bytesRead != -1) ? bytesRead : 0);

                    publishProgress(Long.valueOf(totalBytesRead), Long.valueOf(mResponseBody.contentLength()));
//
//                    if (downloadProgressHandler != null) {
//                        downloadProgressHandler
//                                .obtainMessage(ANConstants.UPDATE,
//                                        new Progress(totalBytesRead, mResponseBody.contentLength()))
//                                .sendToTarget();
//                    }
                    return bytesRead;
                }
            };
        }
    }
}
